TypeScript
Enabling TypeScript supportâ
To enable TypeScript support for a plz project, run the plz typescript command.
The command will create a tsconfig.json file is created in the project.
plz defines a set of reasonable TypeScript defaults in its configs/typescript/tsconfig.base.json. In particular, it establishes a reasonable set of compiler options. The tsconfig.json file, that the command creates, extends the plz configuration - adding included files and aliased paths.
Once the tsconfig.json file has been created, plz's support for TypeScript will be enabled and you'll be able to use .js, .ts and .tsx files in your project. This is identical to the way that create-react-app behaves.
Working with TypeScriptâ
plz will use the version of TypeScript that you have installed in your project. To install TypeScript, run:
yarn add -D typescript --latest --tilde
Generally, it's a good idea to use a tilde version for the typescript dependency, as TypeScript does not follow semver and there can be breaking changes between minor versions.
Although the .jsx extension is optional and .js files can contain JSX, TypeScript files containing JSX must use a .tsx extension. The reason for this is that TypeScript must parse JSX-containing source differently, as it conflicts with some TypeScript syntax.
Since TypeScript ... uses angle brackets for type assertions, combining it with JSXâs syntax would introduce certain parsing difficulties. As a result, TypeScript disallows angle bracket type assertions in
.tsxfiles.
Breaking changesâ
- The
reloadoption for webpackdevconfiguration is no longer supported, aswebpack-hot-middlewareis no longer used.
Implementationâ
TypeScript support within plz tries to leverage as much as possible from react-scripts, for two reasons:
- so that we can write and maintain less code; and
- so that (hopefully) adding support for fast refresh will be a little easier - once it's supported in
react-scripts.
In react-scripts, TypeScript-related parts sit alongside the Babel parts. That is, there aren't completely separate build pipelines; TypeScript support is an add-on. When enabled - by the presence of a tsconfig.json file - Babel parses both JavaScript and TypeScript files. It does not perform type checking of TypeScript files; it simply strips the type annotations and gets on with its build. The type checking is performed by another webpack plugin - fork-ts-checker-webpack-plugin.
The TypeScript-related parts of react-scripts and react-dev-utils are:
- the webpack configuration;
- the dev server configuration;
- the hooking of TypeScript errors;
- the forwarding of TypeScript errors; and
- the TypeScript error formatter.
The biggest change in plz's implementation involved the replacement of the dev server. The previous implementation used webpack-dev-middleware and webpack-hot-middleware. The implementation with TypeScript support uses WebpackDevServer.
The TypeScript plz implementation creates an instance of WebpackDevServer - in much the same way that the start.js in react-scripts does - and calls the createCompiler function in react-dev-utils to hook the TypeScript errors in the hot-module-reloading infrastructure.
WebpackDevServer uses http-proxy-middleware. This is the same middleware that was used in the previous plz implementation, so the proxy configurations are still supported and no changes to existing projects are necessary.
In addition to the changes to the build and serve commands, the storybook and test commands were modified, so that they're aware of TypeScript (.ts and .tsx) files:
- With Storybook, plz receives a base configuration from Storybook, which it then extends. In particular, the webpack configuration is tweaked so that the
babel-loaderis used for TypeScript files. - With Jest, the configuration includes a number of regular expressions: used to match files that need to be transformed (by Babel) and files that contain tests. These regular expressions now match TypeScript files, too.
Because the @babel/preset-typescript is used, specifying the TypeScript extensions in the conifiguration is all that needs to be done.